//
//  SmallDecisionsNavigatorManager.m
//  SmallDecisions
//
//  Created by 李付雄 on 2025/6/14.
//

#import "SmallDecisionsNavigatorManager.h"
#import "SmallDecisionsBaseNavigationController.h"

@interface SmallDecisionsNavigatorManager()

@property (nonatomic, strong) NSMutableArray *navigationControllerList;
@property (nonatomic, strong) NSMutableArray *modalDelegateList;
@property (nonatomic, strong) SmallDecisionsCommonModalTransition *modalDelegate;

@end

@implementation SmallDecisionsNavigatorManager

+ (instancetype)shareInstance {
    static SmallDecisionsNavigatorManager *this = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        
        this = [[SmallDecisionsNavigatorManager alloc] init];
    });
    return this;
}

- (SmallDecisionsCommonModalTransition *)modalDelegate {
    
    return [[SmallDecisionsCommonModalTransition alloc] init];
}

- (NSMutableArray *)navigationControllerList {
    
    if (!_navigationControllerList) {
        
        _navigationControllerList = [[NSMutableArray alloc] init];
    }
    return _navigationControllerList;
}

- (NSMutableArray *)modalDelegateList {
    
    if (!_modalDelegateList) {
        
        _modalDelegateList = [[NSMutableArray alloc] init];
    }
    return _modalDelegateList;
}
+ (void)pushViewController:(UIViewController *)viewController {
    [self pushViewController:viewController animated:YES];
}
+ (void)pushViewController:(UIViewController *)viewController
                  animated:(BOOL)animated {
    
    [self pushViewController:viewController animated:animated finishBlock:nil];
}

+ (void)pushViewController:(UIViewController *)viewController
                  animated:(BOOL)animated
               finishBlock:(void (^ _Nullable)(void))finishBlock {
    
    UINavigationController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
    if (vc && [vc isKindOfClass:[UINavigationController class]]) {
        
        [vc pushViewController:viewController animated:animated];
    } else {
        
        [[SmallDecisionsNavigatorManager shareInstance].mainNavigationController pushViewController:viewController animated:animated];
    }
    
    if (animated) {
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            if (finishBlock) {
                
                finishBlock();
            }
        });
    } else {
        
        if (finishBlock) {
            
            finishBlock();
        }
    }
}

+ (void)popViewControllerAnimated:(BOOL)animated {
    
    [self popViewControllerAnimated:YES finishBlock:nil];
}

+ (void)popViewControllerAnimated:(BOOL)animated
                      finishBlock:(void (^ _Nullable)(void))finishBlock {
    
    [SmallDecisionsNavigatorManager popToViewController:nil animated:animated finishBlock:finishBlock];
}

+ (void)popToViewController:(UIViewController * _Nullable)viewController
                   animated:(BOOL)animated
                finishBlock:(void (^ _Nullable)(void))finishBlock {
    
    if (viewController) {
        
        UINavigationController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
        if (vc && [vc isKindOfClass:[UINavigationController class]]) {
            
            if ([vc.viewControllers containsObject:viewController]) {
                
                [vc popToViewController:viewController animated:animated];
            } else {
                
                if ([[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers containsObject:viewController]) {
                    
                    [[SmallDecisionsNavigatorManager getMainNavigationController] popToViewController:viewController animated:animated];
                }
            }
        } else {
            
            if ([[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers containsObject:viewController]) {
                
                [[SmallDecisionsNavigatorManager shareInstance].mainNavigationController popToViewController:viewController animated:animated];
            }
        }
    } else {
        
        UINavigationController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
        if (vc && [vc isKindOfClass:[UINavigationController class]]) {
            
            [vc popViewControllerAnimated:animated];
        } else {
            
            [[SmallDecisionsNavigatorManager getMainNavigationController] popViewControllerAnimated:animated];
        }
    }
    
    if (animated) {
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            if (finishBlock) {
                
                finishBlock();
            }
        });
    } else {
        
        if (finishBlock) {
            
            finishBlock();
        }
    }
}

+ (UINavigationController *)getMainNavigationController {
    return [SmallDecisionsNavigatorManager shareInstance].mainNavigationController;
}

+ (void)popToRootViewControllerAnimated:(BOOL)animated {
    
    [self popToRootViewControllerAnimated:YES finishBlock:nil];
}

+ (void)popToRootViewControllerAnimated:(BOOL)animated
                            finishBlock:(void (^ _Nullable)(void))finishBlock {
    
    UINavigationController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
    if (vc && [vc isKindOfClass:[UINavigationController class]]) {
        
        [vc popToRootViewControllerAnimated:animated];
    } else {
        
        [[SmallDecisionsNavigatorManager getMainNavigationController] popToRootViewControllerAnimated:animated];
    }
    
    if (animated) {
        
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            if (finishBlock) {
                
                finishBlock();
            }
        });
    } else {
        
        if (finishBlock) {
            
            finishBlock();
        }
    }
}

+ (void)setRootViewController:(UIViewController *)viewController {
    
    UIWindow *keyWindow = [SmallDecisionsNavigatorManager getKeyWindow];
    [UIView transitionWithView:keyWindow duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
        
        [UIView setAnimationsEnabled: NO];
        [keyWindow setRootViewController: viewController];
        [UIView setAnimationsEnabled: YES];
        
    } completion: NULL];
}

+ (UINavigationController *)setRootViewController:(UIViewController *)viewController
                                         animated:(BOOL)animated {
    
    SmallDecisionsBaseNavigationController *nav = [[SmallDecisionsBaseNavigationController alloc] initWithRootViewController:viewController];
    UIWindow *keyWindow = [SmallDecisionsNavigatorManager getKeyWindow];
    if (animated) {
        
        [UIView transitionWithView:keyWindow duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
            
            [UIView setAnimationsEnabled: NO];
            [keyWindow setRootViewController: nav];
            [UIView setAnimationsEnabled: YES];
            
        } completion: NULL];
    } else {
        
        [keyWindow setRootViewController: nav];
    }
    [SmallDecisionsNavigatorManager shareInstance].mainNavigationController = nav;
    return nav;
}

+ (void)insertViewController:(UIViewController *)viewController
                      toIndex:(NSInteger)index
                     animated:(BOOL)animated {
    
    if (!viewController) {
        
        return;
    }
    
    NSArray *viewControllers = [SmallDecisionsNavigatorManager getMainNavigationController].viewControllers;
    NSMutableArray *muViewControllers = [[NSMutableArray alloc] initWithArray:viewControllers];
    
    NSInteger count = muViewControllers.count;
    if (index >= count || index < 0) {
        
        return;
    }
    
    [muViewControllers insertObject:viewController atIndex:index];
    [[SmallDecisionsNavigatorManager getMainNavigationController] setViewControllers:muViewControllers.copy animated:animated];
}

+ (void)redirectViewController:(UIViewController *)viewController
                       toIndex:(NSInteger)index
                      animated:(BOOL)animated {
    
    if (!viewController) {
        
        return;
    }
    
    NSArray *viewControllers = [SmallDecisionsNavigatorManager getMainNavigationController].viewControllers;
    NSMutableArray *muViewControllers = [[NSMutableArray alloc] initWithArray:viewControllers];
    
    NSInteger count = muViewControllers.count;
    if (index >= count || index < 0) {
        
        return;
    }
    
    NSInteger length = count - index;
    // 出栈
    [muViewControllers removeObjectsInRange: NSMakeRange(index, length)];
    // 入栈
    [muViewControllers addObject:viewController];
    [[SmallDecisionsNavigatorManager getMainNavigationController] setViewControllers:muViewControllers.copy animated:animated];
}

+ (void)presentViewController:(UIViewController *)controller
                animationType:(SmallDecisionsAnimationType)animationType  {
    
    [self presentViewController:controller showNavigationBar:YES animationType:animationType];
}

+ (void)presentViewController:(UIViewController *)controller
                animationType:(SmallDecisionsAnimationType)animationType
                       height:(CGFloat)height {
    dispatch_async(dispatch_get_main_queue(), ^{
        
        SmallDecisionsCommonModalTransition *modalDelegate = [SmallDecisionsNavigatorManager shareInstance].modalDelegate;
        modalDelegate.animationType = animationType;
        modalDelegate.showHeight = height;
            
        SmallDecisionsBaseNavigationController *nav = [[SmallDecisionsBaseNavigationController alloc] initWithRootViewController: controller];
        nav.modalPresentationStyle = UIModalPresentationCustom;
        nav.transitioningDelegate  = modalDelegate;
        
        UIViewController *lastVc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
        if (lastVc && [lastVc isKindOfClass:[UINavigationController class]]) {
            
            [((UINavigationController *)lastVc).viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
        } else if (lastVc) {
            
            [lastVc presentViewController:nav animated:YES completion:nil];
        } else {
            
            [[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
        }
        [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList addObject:nav];
        [[SmallDecisionsNavigatorManager shareInstance].modalDelegateList addObject:modalDelegate];
    });
}


+ (void)presentViewController:(UIViewController *)controller
            showNavigationBar:(BOOL)showNavigationBar
                animationType:(SmallDecisionsAnimationType)animationType {
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        SmallDecisionsCommonModalTransition *modalDelegate = [SmallDecisionsNavigatorManager shareInstance].modalDelegate;
        modalDelegate.animationType = animationType;
        if (showNavigationBar) {
            
            SmallDecisionsBaseNavigationController *nav = [[SmallDecisionsBaseNavigationController alloc] initWithRootViewController: controller];
            nav.modalPresentationStyle = UIModalPresentationCustom;
            nav.transitioningDelegate  = modalDelegate;
            
            UIViewController *lastVc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
            if (lastVc && [lastVc isKindOfClass:[UINavigationController class]]) {
                
                [((UINavigationController *)lastVc).viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
            } else if (lastVc) {
                
                [lastVc presentViewController:nav animated:YES completion:nil];
            } else {
                
                [[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
            }
            [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList addObject:nav];
            [[SmallDecisionsNavigatorManager shareInstance].modalDelegateList addObject:modalDelegate];
        } else {
            
            controller.modalPresentationStyle = UIModalPresentationCustom;
            controller.transitioningDelegate  = modalDelegate;
            UIViewController *lastVc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
            if (lastVc && [lastVc isKindOfClass:[UINavigationController class]]) {
                
                [((UINavigationController *)lastVc).viewControllers.lastObject presentViewController:controller animated:YES completion:nil];
            } else if (lastVc) {
                
                [lastVc presentViewController:controller animated:YES completion:nil];
            } else {
                
                [[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers.lastObject presentViewController:controller animated:YES completion:nil];
            }
            [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList addObject:controller];
            [[SmallDecisionsNavigatorManager shareInstance].modalDelegateList addObject:modalDelegate];
        }
    });
}

+ (void)sysPresentViewController:(UIViewController *)controller {
    
    [self sysPresentViewController:controller needNavigationController:YES];
}

+ (void)sysPresentViewController:(UIViewController *)controller
        needNavigationController:(BOOL)need {
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        if (need) {
            
            SmallDecisionsBaseNavigationController *nav = [[SmallDecisionsBaseNavigationController alloc] initWithRootViewController:controller];
            UINavigationController *lastVc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
            if (lastVc && [lastVc isKindOfClass:[UINavigationController class]]) {
                
                [lastVc.viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
            } else if (lastVc) {
                
                [lastVc presentViewController:nav animated:YES completion:nil];
            } else {
                
                [[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers.lastObject presentViewController:nav animated:YES completion:nil];
            }
        } else {
            
            UINavigationController *lastVc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
            if (lastVc && [lastVc isKindOfClass:[UINavigationController class]]) {
                
                [lastVc.viewControllers.lastObject presentViewController:controller animated:YES completion:nil];
            } else if (lastVc) {
                
                [lastVc presentViewController:controller animated:YES completion:nil];
            } else {
                
                [[SmallDecisionsNavigatorManager getMainNavigationController].viewControllers.lastObject presentViewController:controller animated:YES completion:nil];
            }
        }
    });
}

+ (void)dismissViewControllerAnimated:(BOOL)animated
                           completion:(void (^ __nullable)(void))completion {
    
    UIViewController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
    if (vc && [vc isKindOfClass:[UINavigationController class]]) {
        
        [((UINavigationController *)vc).viewControllers.lastObject dismissViewControllerAnimated:animated completion: completion];
        [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList removeLastObject];
        
    } else if (vc) {
        
        [vc dismissViewControllerAnimated:animated completion: completion];
        [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList removeLastObject];
    } else {
        
        [[SmallDecisionsNavigatorManager getMainNavigationController] dismissViewControllerAnimated:animated completion:completion];
    }
    
    // 自定义的转场动画，需要在栈中移除
    if (vc.modalPresentationStyle == UIModalPresentationCustom) {
        
        [[SmallDecisionsNavigatorManager shareInstance].modalDelegateList removeLastObject];
    }
}

+ (void)interactiveDismissViewControllerAnimated:(BOOL)animated
                                      completion:(void (^ __nullable)(void))completion {
    
    UINavigationController *vc = [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList lastObject];
    if (vc && [vc isKindOfClass:[UINavigationController class]]) {
        
        [vc.viewControllers.lastObject dismissViewControllerAnimated:animated completion: completion];
    } else if (vc) {
        
        [vc dismissViewControllerAnimated:animated completion:completion];
    } else {

        [[SmallDecisionsNavigatorManager getMainNavigationController] dismissViewControllerAnimated:animated completion:completion];
    }
}

+ (void)removeDismissViewController {
    
    [[SmallDecisionsNavigatorManager shareInstance].navigationControllerList removeLastObject];
    [[SmallDecisionsNavigatorManager shareInstance].modalDelegateList removeLastObject];
}

+ (UIWindow *)getKeyWindow {
    
    if ( @available(iOS 13.0, *) ) {
        for ( UIScene *scene in UIApplication.sharedApplication.connectedScenes ) {
            if ( [scene isKindOfClass:UIWindowScene.class] ) {
                return [(UIWindowScene *)scene windows].firstObject;
            }
        }
    }
    return [UIApplication sharedApplication].delegate.window;
}


@end
